/*
 * Copyright (C) 2018 Zhejiang xiaominfo Technology CO.,LTD.
 * All rights reserved.
 * Official Web Site: http://www.xiaominfo.com.
 * Developer Web Site: http://open.xiaominfo.com.
 */

package com.github.xiaoymin.deploy;

import com.github.xiaoymin.deploy.common.PluginConst;
import com.github.xiaoymin.deploy.model.DeployHelperConfiguration;
import com.github.xiaoymin.deploy.model.DeployHelperDeploy;
import com.github.xiaoymin.deploy.model.DeployRequest;
import com.github.xiaoymin.deploy.plugin.DeployService;
import com.github.xiaoymin.deploy.plugin.impl.BackupService;
import com.github.xiaoymin.deploy.plugin.impl.StartupService;
import com.github.xiaoymin.deploy.plugin.impl.StopService;
import com.github.xiaoymin.deploy.plugin.impl.UploadService;
import org.apache.maven.project.MavenProject;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/***
 * 核心类
 * @since:deploy-helper 1.0
 * @author <a href="mailto:xiaoymin@foxmail.com">xiaoymin@foxmail.com</a> 
 * 2020/07/02 10:54
 */
public class DeployHelper {

    public static final DeployHelper me=new DeployHelper();
    private Map<String, DeployService> pluginMap;

    private MavenProject mavenProject;

    private final DeployHelperConfiguration deployHelperConfiguration;

    Logger logger= LoggerFactory.getLogger(DeployHelper.class);

    private DeployHelper(){
        deployHelperConfiguration=new DeployHelperConfiguration();
        pluginMap=new HashMap<>();
        initPlugins();
    }

    /**
     * 初始化Plugin
     */
    private void initPlugins() {
        this.addPlugin(new StartupService());
        this.addPlugin(new BackupService());
        this.addPlugin(new StopService());
        this.addPlugin(new UploadService());
    }

    private void addPlugin(DeployService plugin){
        this.pluginMap.put(plugin.getPluginName(),plugin);
    }

    public void setMavenProject(MavenProject mavenProject) {
        this.mavenProject = mavenProject;
    }

    /**
     * 初始化配置文件
     * @param deployConfigFile 配置文件
     */
    public void initConfig(File deployConfigFile){
        logger.info("Start Init DeployHelperXmlConfigFile,path:{}",deployConfigFile.getPath());
        try {
            deployHelperConfiguration.load(deployConfigFile);
            deployHelperConfiguration.profile();
        } catch (DocumentException e) {
            logger.error("Init DeployHelperConfig Failed,Message:{}",e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 开始执行操作
     */
    public void execute(){
        logger.info("Start execute.");
        if (this.deployHelperConfiguration.getProfileDeploy()==null||this.deployHelperConfiguration.getProfileServer()==null){
            throw new RuntimeException("profile deploy or server can't be empty!!!");
        }
        logger.info("deploy profile info:{}",this.deployHelperConfiguration.getProfileDeploy().toString());
        logger.info("server profile info:{}",this.deployHelperConfiguration.getProfileServer().toString());
        DeployHelperConnection connection=new DeployHelperConnection(this.deployHelperConfiguration.getProfileServer());
        //获取激活的profile配置文件
        DeployHelperDeploy helperDeploy=deployHelperConfiguration.getProfileDeploy();
        try {
            logger.info("check deploy config...");
            helperDeploy.validate();
            connection.openSession();
            //执行stop脚本
            DeployRequest deployRequest=new DeployRequest(connection,helperDeploy,mavenProject);
            pluginMap.get(PluginConst.PLUGIN_STOP_SERVICE).action(deployRequest);
            //sleep 5秒钟,保证服务端进程关闭成功
            TimeUnit.SECONDS.sleep(5L);
            //备份策略
            pluginMap.get(PluginConst.PLUGIN_BACKUP_SERVICE).action(deployRequest);
            //开始上传本地jar文件
            pluginMap.get(PluginConst.PLUGIN_UPLOAD_SERVICE).action(deployRequest);
            TimeUnit.SECONDS.sleep(2L);
            pluginMap.get(PluginConst.PLUGIN_START_SERVICE).action(deployRequest);
            logger.info("Deploy Successful.");
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        }finally {
            connection.closeSession();
        }
    }

}
